package com.zp.demo.repush.service.impl;

import com.zp.demo.repush.exception.RePushException;
import com.zp.demo.repush.service.DoRePushExcuteService;
import com.zp.demo.repush.service.func.IsSucessFunc;
import com.zp.demo.repush.service.defined.DefinedRePushInter;
import com.zp.demo.repush.vo.BaseRePushVo;
import com.zp.demo.repush.vo.RePushStrategyEntity;
import lombok.extern.log4j.Log4j2;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.ApplicationContext;
import org.springframework.stereotype.Service;

import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.util.Map;
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;

@Service
@Log4j2
public class DoRePushExcuteServiceImpl implements DoRePushExcuteService {
    @Autowired
    private Map<String,DefinedRePushInter> defindRePushServiceMap;
    @Autowired
    private ApplicationContext applicationContext;
    @Autowired
    private Map<String,Method> rePushHandleMap;
    @Autowired
    private Map<String,RePushStrategyEntity> exceptionStrategy;
    private Lock lock = new ReentrantLock();
    @Override
    public boolean excute(String methodId, Object[] args, IsSucessFunc isSucessFunc, BaseRePushVo baseRePushVo)
    {
        Object result = this.excuteGetResult(methodId,args,baseRePushVo);
        // 结果
        if(result != null){
            baseRePushVo.setOldResult(result);
        }
        if(isSucessFunc == null){
            Class successClazz = null;
            try {
                successClazz = Class.forName(baseRePushVo.getIsSuccessClass());
                try {
                    isSucessFunc = (IsSucessFunc) successClazz.newInstance();
                } catch (InstantiationException e) {
                    e.printStackTrace();
                } catch (IllegalAccessException e) {
                    e.printStackTrace();
                }
            } catch (ClassNotFoundException e) {
                e.printStackTrace();
            }
        }
        return isSucessFunc.isSucess(result);
    }

    @Override
    public Object excuteGetResult(String methodId, Object[] args, BaseRePushVo baseRePushVo) {
        // 查询 是否有自己的 实现
        DefinedRePushInter definedRePushInter = defindRePushServiceMap.get(methodId);
        if (definedRePushInter != null) {
            return definedRePushInter.pushDataService(args);
        }
        // 反射调用方法执行
        else {
            Method method = rePushHandleMap.get(methodId);
            Object install = applicationContext.getBean(method.getDeclaringClass());
            Object result;
            try {
                result = method.invoke(install, args);
                return result;
            }  catch (RePushException e) {
                log.info("继续异常");
                return false;
            }catch (IllegalAccessException e) {
                e.printStackTrace();
            } catch (InvocationTargetException e) {
                if(e.getTargetException() instanceof RePushException){
                    log.info("继续异常");
                }else{
                    log.info("继续异常");
                }
            } catch (Exception e) {
                return false;
            }
        }
        return false;
    }

    /**
     * 获取配置的策略
     * @param exceptionKey
     * @return
     */
    @Override
    public RePushStrategyEntity getStrategyProperties(String exceptionKey) {
        // 获取重推策略
        RePushStrategyEntity baseStrategy = exceptionStrategy.get(exceptionKey);
        if(baseStrategy == null){
            baseStrategy = exceptionStrategy.get("master");
        }
        return baseStrategy;
    }
}
